Allow csd for override-redirect windows
authorMatthias Clasen <mclasen@redhat.com>
Fri, 6 Jun 2014 21:59:38 +0000 (17:59 -0400)
committerMatthias Clasen <mclasen@redhat.com>
Mon, 9 Jun 2014 18:01:42 +0000 (14:01 -0400)
This commit makes it possible to use client-side decorations for
override-redirect windows by calling _gtk_window_request_csd()
before realizing the window. Since the wm won't do interactive
resizing for us in this case anyway, don't bother creating
the border windows we use for this purpose on regular toplevels.

To make this accessible to themes, we set a "csd" style class
on client-side decorated windows. With this, .window-frame.csd.menu
can be used to define the shadow for csd menus, and .menu can be
used to define a border for menus under non-composited wms.

https://bugzilla.gnome.org/show_bug.cgi?id=731187

gtk/gtkwindow.c
gtk/gtkwindowprivate.h

index c0cefff109a0fba2ca20ae5e1e50ec19312ba563..2db30154012b7e48fec958b2a1feae186702ebfe 100644 (file)
@@ -224,6 +224,7 @@ struct _GtkWindowPrivate
                                             * grip-visible" notification
                                             */
   guint    gravity                   : 5; /* GdkGravity */
+  guint    csd_requested             : 1;
   guint    client_decorated          : 1; /* Decorations drawn client-side */
   guint    custom_title              : 1; /* app-provided titlebar if CSD can't
                                            * be enabled */
@@ -3817,6 +3818,7 @@ gtk_window_enable_csd (GtkWindow *window)
   gtk_widget_set_visual (widget, visual);
 
   priv->client_decorated = TRUE;
+  gtk_style_context_add_class (gtk_widget_get_style_context (widget), GTK_STYLE_CLASS_CSD);
 }
 
 static void
@@ -3874,6 +3876,7 @@ gtk_window_set_titlebar (GtkWindow *window,
     {
       priv->custom_title = FALSE;
       priv->client_decorated = FALSE;
+      gtk_style_context_remove_class (gtk_widget_get_style_context (widget), GTK_STYLE_CLASS_CSD);
       return;
     }
 
@@ -5545,12 +5548,23 @@ create_titlebar (GtkWindow *window)
   return titlebar;
 }
 
+void
+_gtk_window_request_csd (GtkWindow *window)
+{
+  GtkWindowPrivate *priv = window->priv;
+
+  priv->csd_requested = TRUE;
+}
+
 static gboolean
 gtk_window_should_use_csd (GtkWindow *window)
 {
   GtkWindowPrivate *priv = window->priv;
   const gchar *csd_env;
 
+  if (priv->csd_requested)
+    return TRUE;
+
   if (!priv->decorated)
     return FALSE;
 
@@ -5584,6 +5598,9 @@ create_decoration (GtkWidget *widget)
 
   gtk_window_enable_csd (window);
 
+  if (priv->type == GTK_WINDOW_POPUP)
+    return;
+
   if (priv->title_box == NULL)
     {
       priv->titlebar = create_titlebar (window);
@@ -6319,7 +6336,7 @@ gtk_window_realize (GtkWidget *widget)
 
   attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL;
 
-  if (priv->client_decorated)
+  if (priv->client_decorated && priv->type == GTK_WINDOW_TOPLEVEL)
     {
       GdkCursorType cursor_type[8] = {
         GDK_TOP_LEFT_CORNER,
index eb827f5cbc5e0e074c0b9dadb0b2476c3b0abe5a..3d7b08685df75c9ce108a0f03e031f71e01f7ef6 100644 (file)
@@ -93,6 +93,8 @@ void            _gtk_window_get_shadow_width (GtkWindow *window,
 
 void            _gtk_window_toggle_maximized (GtkWindow *window);
 
+void            _gtk_window_request_csd (GtkWindow *window);
+
 /* Window groups */
 
 GtkWindowGroup *_gtk_window_get_window_group (GtkWindow *window);